package biz.datalk.industrialland.common.component.redis;

import biz.datalk.industrialland.common.def.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.StandardCharsets;

/**
 * 自定义key 序列化
 *
 * @author tarofang@163.com
 * @date 2020-02-21
 */
@Slf4j
public class DatalkRedisKeyPrefixSerializer implements RedisSerializer<String> {

    public static final String REDIS_KEY_REMOVE_PREFIX_PATTERN = CommonConstant.REDIS_KEY_REMOVE_PREFIX_PATTERN; // "$_$";

    private final String keyPrefix;

    public DatalkRedisKeyPrefixSerializer(String keyPrefix) {
        this.keyPrefix = keyPrefix;
    }

    /**
     * key 序列化
     * $_$ 开头的 key 不添加前缀
     */
    @Override
    public byte[] serialize(String string) throws SerializationException {
        String key;
        if (StringUtils.startsWith(string, REDIS_KEY_REMOVE_PREFIX_PATTERN)) {
            key = string.substring(REDIS_KEY_REMOVE_PREFIX_PATTERN.length());
        } else {
            key = keyPrefix + string;
        }

        if (log.isDebugEnabled()) {
            log.debug("[key={}, oldKey={}, keyPrefix={}]", key, string, keyPrefix);
        }
        return key.getBytes(StandardCharsets.UTF_8);
    }

    /** key 反序列化 */
    @Override
    public String deserialize(byte[] bytes) throws SerializationException {
        String saveKey = new String(bytes, StandardCharsets.UTF_8);
        String resultKey = saveKey;
        if (saveKey.startsWith(keyPrefix)) {
            resultKey = saveKey.substring(keyPrefix.length());
        } else {
            if (log.isTraceEnabled()) {
                log.trace("No prefix specified. [saveKey={}, keyPrefix={}]", saveKey, keyPrefix);
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("[saveKey={}, resultKey={}, keyPrefix={}]", saveKey, resultKey, keyPrefix);
        }

        return resultKey;
    }
}
